# -*- coding: utf-8 -*-
"""
Created on Tue May 16 16:41:56 2023

@author: zh-gsyw-wn
"""

#%%

import pandas as pd
import numpy as np
# result = pd.read_excel('result.xlsx')
# dfo_cut = pd.read_excel('dfo_cut.xlsx').set_index('rating_id')
# rule_data = pd.read_excel('df_dim.xlsx',sheet_name='rule_config')
import matplotlib.pyplot as plt

#%%

def ruleApply(dfo_cut,model_type,rule_data,result):
    print('-------------------开始施加策略------------------------')
    rule_data = which_model_rule(model_type, rule_data) #对数据表进行切片
    # print(len(rule_data),'已获取')
    flag = find_rule(dfo_cut,rule_data)                 #获取到记录flag
    # print(len(flag),'已获取')
    rule_record = make_rule_record(flag, model_type)    #制作策略记录表
    
    result = adjust_score(result,flag,rule_data)        #给出得分
    print('策略施加完毕')
    return result,rule_record


def adjust_score(result,flag,rule_data):
    if len(rule_data) == 0:
        print('规则表中无规则 请检查')
        return result
    print(0)
    dft = pd.merge(result,flag,on='rating_id')
    print(1)
    if 'rating_id' in flag.columns:
        del flag['rating_id']
    for col in flag.columns.to_list():
        dfr = rule_data.loc[rule_data.code == col]
        score_type = dfr['dim_score'].values[0]
        dert = dfr['add_score'].values[0]
        # print(col)
        dft.loc[dft[col] == 1,score_type] = dft[score_type] + dert 

    dft.loc[dft.e_score < 0,'e_score'] =  0
    dft.loc[dft.s_score < 0,'s_score'] =  0
    dft.loc[dft.g_score < 0,'g_score'] =  0
    dft.esg_score = dft.e_score + dft.s_score + dft.g_score 
    return dft[['rating_id','e_score','s_score','g_score','esg_score','model_type']]


def make_rule_record(flag,model_type,batch_id='ESG_202305_DATA'):
    if len(flag) == 0:
        return pd.DataFrame()
    flag2 = flag.copy()
    rule_record = flag2.set_index('rating_id').stack().reset_index()
    rule_record.columns = ['rating_id','rule_code','content']
    del rule_record['content']
    rule_record['model_type'] = model_type
    rule_record['batch_id'] = batch_id 
    return rule_record 



def find_rule(dfo_cut,rule_data):
    if len(rule_data) == 0:
        print('规则表无数据请检查 此处已经跳过施加规则')
        return pd.DataFrame()
    lst_record = [] #取数据用
    dic_record = {}
    for i in range(len(rule_data)):
        dfr = rule_data.iloc[i].to_frame().T
        if dfr['var'].values[0] in dfo_cut.columns:
            var = dfr['var'].values[0]
            value = dfr['value'].values[0]
            dim = dfr['dim'].values[0]
            dim_score = dfr['dim_score'].values[0]
            add_score = dfr['add_score'].values[0]
            code = dfr['code'].values[0]
            # print(code)
            rule_code = dfr['rule_code'].values[0]
            method = dfr['method'].values[0]
            type_ = dfr['type'].values[0]
            if type_ == '字符串':
                if type(value) is np.float64:
                    value = str(int(value))
                else:
                    value = str(value) 
            # print(value,type(value))

        #记录
            lst_record.append(code)
            # print(lst_record)
            dic_record.update({code:rule_code}) 

            #计算满足条件的
            cond = compute(method,dfo_cut[var],value) 

            #制作记录标签
            dfo_cut.loc[cond,code] = 1
            dfo_cut[code] = dfo_cut[code].fillna(0)
        # print(dfo_cut.columns)
#             display(dfo_cut[code].value_counts(dropna=False))
#             print(lst_record)
    return dfo_cut[list(set(lst_record)) + ['rating_id']].replace(0,np.nan)


def which_model_rule(model_type,rule_data):
    if len(rule_data) == 0:
        print('规则表无数据 请检查')
        return pd.DataFrame()
    model_type_scale = model_type[1]             #大中 小微 不区分
    rule_data = rule_data.loc[rule_data.scale.isin([float(model_type_scale),str(model_type_scale),int(model_type_scale)])] #按模型筛选
    rule_data = rule_data.reset_index(drop=True)
    return rule_data

def compute(method,data,x):
    if method == '>':
        return data > x
    elif method == '=':
        return data == x
    elif method == '<':
        return data < x 
    elif method == '>=':
        return data >= x
    elif method == '<=':
        return data <= x 
    else:
        print('计算方法配置错误 请检查rule_data表是否规范')

